package mn.idax.exchange.otc.service.impl;

import mn.idax.exchange.otc.constant.CommonConstant;
import mn.idax.exchange.otc.domain.EmaiDto.BaseEmaiDTO;
import mn.idax.exchange.otc.domain.OTCArbitrationJudgeRequest;
import mn.idax.exchange.otc.domain.SimpleUserLanguage;
import mn.idax.exchange.otc.entity.*;
import mn.idax.exchange.otc.enums.JiGuangPushEnum;
import mn.idax.exchange.otc.enums.MessageNotifyEnum;
import mn.idax.exchange.otc.enums.OTCArbitrationEnum;
import mn.idax.exchange.otc.enums.OrderState;
import mn.idax.exchange.otc.service.*;
import mn.idax.exchange.otc.util.LogUtils;
import mn.idax.exchange.otc.util.MessageNotifyUtils;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import mn.idax.exchange.otc.domain.OrderChangeDTO;
import mn.idax.exchange.otc.enums.response.OTCArbitrationResponseEnum;
import mn.idax.exchange.otc.enums.response.OrderResponseEnum;
import mn.idax.exchange.otc.exception.IdaxException;
import mn.idax.exchange.otc.mapper.OTCArbitrationDetailMapper;
import mn.idax.exchange.otc.mapper.OTCArbitrationMapper;

import java.text.MessageFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * @Auther: shihaiming
 * @Date: 2018/08/15
 * @Description:
 */
@Service
public class OTCArbitrationServiceImpl implements OTCArbitrationService {

    private static ExecutorService executorService = Executors.newFixedThreadPool(2);

    @Autowired
    private OTCArbitrationMapper otcArbitrationMapper;
    @Autowired
    private OTCArbitrationDetailMapper otcArbitrationDetailMapper;
    @Autowired
    private OTCOrderService otcOrderService;

    @Autowired
    private SqsService sqsService;

    @Value("${sqs.queue.name}")
    private String sqsQueueName;

    @Autowired
    private JiGuangService jiGuangService;

    @Autowired
    private UserLanguageService userLanguageService;






    @Transactional(rollbackFor=Exception.class)
    @Override
    public void add(OTCArbitration otcArbitration, OTCArbitrationDetail otcArbitrationDetail, OrderChangeDTO orderChangeDTO,boolean isBuyer,OTCOrder otcOrder) {
        //检查是否已申请仲裁
    	if(otcArbitrationMapper.selectByOrderId(otcArbitration.getOrderid()) > 0) {
    		throw new IdaxException(OTCArbitrationResponseEnum.HAVE_APPLIED.getCode());
    	}
    	
    	//保存到仲裁表
    	int count = otcArbitrationMapper.insertSelective(otcArbitration);
    	if(count == 0) {
    	    throw new IdaxException(OTCArbitrationResponseEnum.INSERT_FAIL.getCode());
        }
    	
    	//仲裁明细表关联仲裁表主键
    	otcArbitrationDetail.setArbitrationid(otcArbitration.getId());
    	
    	//保存仲裁明细表
    	count = otcArbitrationDetailMapper.insertSelective(otcArbitrationDetail);
    	if(count == 0) {
    	    throw new IdaxException(OTCArbitrationResponseEnum.INSERT_FAIL.getCode());
        }

    	//设计如此 恶意评价更新订单状态后 判断任意一方胜都会有问题
    	if (!otcArbitration.getType().equals(6)){
            //更新订单状态
            if(!otcOrderService.updateOrderStateCommon(otcOrder,orderChangeDTO, otcArbitration.getPleaduserid())){
                throw new IdaxException(OrderResponseEnum.UPDATE_ORDERSTATEFAIL.getRespCode());
            }

            //推送邮件和短信
            executorService.execute(new Runnable() {
                @Override
                public void run() {
                    arbitrationCreatedPush(otcOrder,isBuyer);
                    //极光推送给双方  您有一笔交易订单因为逾时未处理，由系统取消交易
                    jiGuangService.pushToBuyerAndSeller(otcOrder, JiGuangPushEnum.ARBITRATION_CREATE);
                }
            });
        }

    }

    @Override
    public boolean pushJudgeInfo(OTCArbitrationJudgeRequest judge){
        OTCArbitration otcArbitration = this.otcArbitrationMapper.selectByPrimaryKey(judge.getId());
        if (otcArbitration != null){
            OTCOrder order = this.otcOrderService.selectByPrimaryKey(otcArbitration.getOrderid());

            boolean isBuyer = false;
            if (otcArbitration.getPleaduserid().equals(order.getBuyer())){
                isBuyer = true;
            }
            MessageNotifyEnum.BodyTemplate bodyTemplate = null;
            Integer judgeType = judge.getJudgeType();

            // 1.申诉人为买家，判定买方胜利，推送申诉成功
            if (isBuyer && OTCArbitrationEnum.JudgeType.success.getType().equals(judgeType)){
                bodyTemplate = MessageNotifyEnum.BodyTemplate.arbitration_success;
            // 2.申诉人为卖方，判定卖方胜利，推送申诉成功
            }else if (!isBuyer && OTCArbitrationEnum.JudgeType.fail.getType().equals(judgeType)){
                bodyTemplate = MessageNotifyEnum.BodyTemplate.arbitration_success;
            }else{
                bodyTemplate = MessageNotifyEnum.BodyTemplate.arbitration_fail;
            }

            MessageNotifyUtils.sendNotify(otcArbitration.getPleaduserid(),
                    otcArbitration.getId(),
                    bodyTemplate);

            //推送邮件和短信
            boolean finalIsBuyer = isBuyer;
            executorService.execute(new Runnable() {
                @Override
                public void run() {
                    arbitrationFinishPush(order, finalIsBuyer,judgeType);
                }
            });
            return true;
        }
        return false;
    }

    @Override
    public String showDetail(Integer userId , OTCArbitrationJudgeRequest judge){
        OTCArbitration otcArbitration = this.otcArbitrationMapper.selectByPrimaryKey(judge.getId());
        if (otcArbitration != null){

            OTCOrder order = this.otcOrderService.selectByPrimaryKey(otcArbitration.getOrderid());

            OTCArbitrationEnum.Template template = OTCArbitrationEnum.Template.seller_win_detail;

            boolean isBuyer = false;
            if (otcArbitration.getPleaduserid().equals(order.getBuyer())){
                isBuyer = true;
            }
            // 1.申诉人为买家，判定买方胜利，推送申诉成功
            if (isBuyer && OTCArbitrationEnum.sub_state_buy_win.getCode().equals(otcArbitration.getSubstatus())){
                template = OTCArbitrationEnum.Template.buy_win_detail;
                // 2.申诉人为卖方，判定卖方胜利，推送申诉成功
            }else if (!isBuyer && OTCArbitrationEnum.sub_state_sell_win.getCode().equals(otcArbitration.getSubstatus())){
                template = OTCArbitrationEnum.Template.buy_win_detail;
            }

            return MessageFormat.format(template.getDetail() , order.getNumber() , "a" + order.getNumber());
        }
        return null;
    }

    @Override
    public OTCArbitration getOTCArbitration(Integer userId, Integer orderid) {

        OTCArbitrationExample example = new OTCArbitrationExample();
        example.createCriteria().andPleaduseridEqualTo(userId).andOrderidEqualTo(orderid);
        List<OTCArbitration> otcArbitrations = otcArbitrationMapper.selectByExample(example);
        return otcArbitrations.isEmpty() ? null : otcArbitrations.get(0);
    }


    /**
     *  发送邮件通知  发起仲裁
     *  买家发起的申诉 卖家是被申诉方  卖家发起的申诉 买家是被申诉方
     * @param otcOrder
     * @param isBuyer
     */
    public void arbitrationCreatedPush(OTCOrder otcOrder,boolean isBuyer){
        LogUtils.info(this.getClass(),"arbitrationCreatedPush start ...");
        try {
//            User buyer = userService.getUserById(otcOrder.getBuyer());
//            User seller = userService.getUserById(otcOrder.getSeller());
            String buyererNickName = MessageNotifyUtils.getNotifyNickName(otcOrder.getBuyer());
            String sellerNickName = MessageNotifyUtils.getNotifyNickName(otcOrder.getSeller());

            List<SimpleUserLanguage> languages = userLanguageService.getBuyerAndSellerSimpleLanguage(otcOrder.getBuyer(), otcOrder.getSeller());

            if (isBuyer) {
                //发给-申诉方,申诉方为买家   你已向用户“张三”发起申诉，申诉订单号为001120181212070409000061s，请及时登录网站进行查看。
                BaseEmaiDTO appeal = new BaseEmaiDTO();
                appeal.setNickName(sellerNickName);
                appeal.setOrderId(otcOrder.getNumber());
                sqsService.sendEmailMessage(CommonConstant.EmailType.ARBITRATION_CREATE_TO_APPEALER, languages.get(0).getEmail(), languages.get(0).getLanguage(), otcOrder.getId(),
                        sqsQueueName, appeal);

                //发给-被申诉方,申诉方为卖家  用户“张三”已向你发起申诉，申诉订单号为001120181212070409000061s，请及时登录网站进行查看。
                BaseEmaiDTO beAppeal = new BaseEmaiDTO();
                beAppeal.setNickName(buyererNickName);
                beAppeal.setOrderId(otcOrder.getNumber());
                sqsService.sendEmailMessage(CommonConstant.EmailType.ARBITRATION_CREATE_TO_BEAPPEALER, languages.get(1).getEmail(), languages.get(1).getLanguage(), otcOrder.getId(),
                        sqsQueueName, beAppeal);

            } else {
                //发给-申诉方,申诉方为卖家   你已向用户“张三”发起申诉，申诉订单号为001120181212070409000061s，请及时登录网站进行查看。
                BaseEmaiDTO appeal = new BaseEmaiDTO();
                appeal.setNickName(buyererNickName);
                appeal.setOrderId(otcOrder.getNumber());
                sqsService.sendEmailMessage(CommonConstant.EmailType.ARBITRATION_CREATE_TO_APPEALER, languages.get(1).getEmail(), languages.get(1).getLanguage(), otcOrder.getId(),
                        sqsQueueName, appeal);

                //发给-被申诉方,申诉方为买家  用户“张三”已向你发起申诉，申诉订单号为001120181212070409000061s，请及时登录网站进行查看。
                BaseEmaiDTO beAppeal = new BaseEmaiDTO();
                beAppeal.setNickName(sellerNickName);
                beAppeal.setOrderId(otcOrder.getNumber());
                sqsService.sendEmailMessage(CommonConstant.EmailType.ARBITRATION_CREATE_TO_BEAPPEALER, languages.get(0).getEmail(), languages.get(0).getLanguage(), otcOrder.getId(),
                        sqsQueueName, beAppeal);
            }
        } catch (Exception e) {
            LogUtils.warn(this.getClass(),"arbitrationCreated but push email and message failed..." + ExceptionUtils.getStackTrace(e));
        }
    }

    /**
     * 发送邮件通知  仲裁完成
     * 1）买家发起申诉，若仲裁结果为买家胜，表示买家获胜，申诉成立；
     * 2）买家发起申诉，若仲裁结果为卖家胜，表示买家败诉，申诉不成立；
     * 3）卖家发起申诉，若仲裁结果为买家胜，表示买家胜诉，申诉不成立；
     * 4）卖家发起申诉，若仲裁结果为卖家胜，表示卖家败诉，申诉成立；
     * @param otcOrder
     * @param isBuyer
     * @param judgeType
     */
    public void arbitrationFinishPush(OTCOrder otcOrder,boolean isBuyer,Integer judgeType){

        /**
         * 申诉成立
         * 你对用户“张三”发起的申诉成立，平台现已完成仲裁，可登录网站查看结果。
         * 用户“张三”对你发起的申诉成立，平台已完成仲裁，你可登录网站查看结果。
         * 申诉不成立
         * 你向用户“张三”发起的申诉不成立，平台已完成仲裁，可登录网站进行查看详情。
         * 用户“张三”向你发起的申诉不成立，平台已完成仲裁，可登陆网站查看详情。
         */

        LogUtils.info(this.getClass(),"arbitrationFinishPush start ...");
        try {
//            User buyer = userService.getUserById(otcOrder.getBuyer());
//            User seller = userService.getUserById(otcOrder.getSeller());
            String buyererNickName = MessageNotifyUtils.getNotifyNickName(otcOrder.getBuyer());
            String sellerNickName = MessageNotifyUtils.getNotifyNickName(otcOrder.getSeller());
            List<SimpleUserLanguage> languages = userLanguageService.getBuyerAndSellerSimpleLanguage(otcOrder.getBuyer(), otcOrder.getSeller());

            BaseEmaiDTO buyerDTO = new BaseEmaiDTO();
            BaseEmaiDTO sellerDTO = new BaseEmaiDTO();
            //申诉成立 1 买方胜 2 卖方胜
            if ((isBuyer && judgeType.equals(1)) || (!isBuyer && judgeType.equals(2))){
                //申诉人是买家
                if (isBuyer){
                    //发给买家 买家成立
                    buyerDTO.setNickName(sellerNickName);
                    buyerDTO.setOrderId(otcOrder.getNumber());
                    sqsService.sendEmailMessage(CommonConstant.EmailType.ARBITRATION_FINISH_TO_APPEALER_WIN, languages.get(0).getEmail(), languages.get(0).getLanguage(), otcOrder.getId(),
                            sqsQueueName, buyerDTO);

                    //发给卖家 卖家成立
                    sellerDTO.setNickName(buyererNickName);
                    sellerDTO.setOrderId(otcOrder.getNumber());
                    sqsService.sendEmailMessage(CommonConstant.EmailType.ARBITRATION_FINISH_TO_BEAPPEALER_WIN, languages.get(1).getEmail(), languages.get(1).getLanguage(), otcOrder.getId(),
                            sqsQueueName, sellerDTO);
                    //申诉人是卖家
                } else {
                    // 发给卖家 卖家成立
                    sellerDTO.setNickName(buyererNickName);
                    sellerDTO.setOrderId(otcOrder.getNumber());
                    sqsService.sendEmailMessage(CommonConstant.EmailType.ARBITRATION_FINISH_TO_APPEALER_WIN, languages.get(1).getEmail(), languages.get(1).getLanguage(), otcOrder.getId(),
                            sqsQueueName, sellerDTO);

                    //发给买家 买家不成立
                    buyerDTO.setNickName(sellerNickName);
                    buyerDTO.setOrderId(otcOrder.getNumber());
                    sqsService.sendEmailMessage(CommonConstant.EmailType.ARBITRATION_FINISH_TO_BEAPPEALER_WIN, languages.get(0).getEmail(), languages.get(0).getLanguage(), otcOrder.getId(),
                            sqsQueueName, buyerDTO);
                }

                //申诉不成立
            } else {
                //申诉人是买家
                if (isBuyer){
                    //发给买家 买家不成立
                    buyerDTO.setNickName(sellerNickName);
                    buyerDTO.setOrderId(otcOrder.getNumber());
                    sqsService.sendEmailMessage(CommonConstant.EmailType.ARBITRATION_FINISH_APPEALER_LOSE, languages.get(0).getEmail(), languages.get(0).getLanguage(), otcOrder.getId(),
                            sqsQueueName, buyerDTO);
                    //发给卖家 卖家成立
                    sellerDTO.setNickName(buyererNickName);
                    sellerDTO.setOrderId(otcOrder.getNumber());
                    sqsService.sendEmailMessage(CommonConstant.EmailType.ARBITRATION_FINISH_BEAPPEALER_LOSE, languages.get(1).getEmail(), languages.get(1).getLanguage(), otcOrder.getId(),
                            sqsQueueName, sellerDTO);

                    //申诉人是卖家
                } else {
                    //发给卖家 卖家不成立
                    sellerDTO.setNickName(buyererNickName);
                    sellerDTO.setOrderId(otcOrder.getNumber());
                    sqsService.sendEmailMessage(CommonConstant.EmailType.ARBITRATION_FINISH_APPEALER_LOSE, languages.get(1).getEmail(), languages.get(1).getLanguage(), otcOrder.getId(),
                            sqsQueueName, sellerDTO);
                    //发给买家 买家成立
                    buyerDTO.setNickName(sellerNickName);
                    buyerDTO.setOrderId(otcOrder.getNumber());
                    sqsService.sendEmailMessage(CommonConstant.EmailType.ARBITRATION_FINISH_BEAPPEALER_LOSE, languages.get(0).getEmail(), languages.get(0).getLanguage(), otcOrder.getId(),
                            sqsQueueName, buyerDTO);

                }
            }
        } catch (Exception e) {
            LogUtils.warn(this.getClass(),"arbitrationFinish but push email and message failed..." + ExceptionUtils.getStackTrace(e));
        }

    }


    /**
     * 获取仲裁订单已过36小时的仲裁请求
     * @param
     * @return
     */
    @Override
    public List<OTCArbitration> getNeedJiGuangPush(Date date) {

        //当前时间-36小时
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.HOUR, -36);
        Date expireTime = calendar.getTime();

        return otcArbitrationMapper.getNeedJiGuangPush(expireTime);

    }


}
